#include "RenderPch.h"

#include "CameraNavigation.h"

CameraNavigation::CameraNavigation(void) :
m_moveSpeed( 10.f )
,m_frontMove( FALSE )
,m_backMove( FALSE )
,m_leftMove( FALSE )
,m_rightMove( FALSE )
,m_yawPitchRotation( FALSE )
,m_rollRotation( FALSE )
{
	m_cameraTransform.Identity();
	m_projTransform.Identity();
}

CameraNavigation::~CameraNavigation(void)
{
}

void CameraNavigation::Update( float dTime )
{
	Vector3 position = m_cameraTransform.GetTranslation();

	if( m_frontMove )
	{
		Vector3 dir( 0.f, 0.f, 1.f );
		m_cameraTransform.TransformNormal( dir, dir );

		position += (m_moveSpeed * dTime * dir);
	}

	if( m_leftMove )
	{
		Vector3 dir( -1.f, 0.f, 0.f );
		m_cameraTransform.TransformNormal( dir, dir );

		position += (m_moveSpeed * dTime * dir);
	}

	if( m_backMove )
	{
		Vector3 dir( 0.f, 0.f, -1.f );
		m_cameraTransform.TransformNormal( dir, dir );

		position += (m_moveSpeed * dTime * dir);
	}

	if( m_rightMove )
	{
		Vector3 dir( 1.f, 0.f, 0.f );
		m_cameraTransform.TransformNormal( dir, dir );

		position += (m_moveSpeed * dTime * dir);
	}

	Matrix translationMat;
	translationMat.MakeTranslation( position );

	Vector3 ypr = m_cameraTransform.GetYawPitchRoll();
	Matrix rotationMat;
	rotationMat.MakeRotation( ypr );

	m_cameraTransform = rotationMat * translationMat;
}

void CameraNavigation::HandleEvent( UINT message, WPARAM wParam, LPARAM lParam )
{
	switch( message )
	{
	case WM_KEYDOWN:
		{
			switch( wParam )
			{
			case 'W':
				{
					m_frontMove = TRUE;
				}
				break;
			case 'A':
				{
					m_leftMove = TRUE;
				}
				break;
			case 'S':
				{
					m_backMove = TRUE;
				}
				break;
			case 'D':
				{
					m_rightMove = TRUE;
				}
				break;
			}
		}
		break;

	case WM_KEYUP:
		{
			switch( wParam )
			{
			case 'W':
				{
					m_frontMove = FALSE;
				}
				break;
			case 'A':
				{
					m_leftMove = FALSE;
				}
				break;
			case 'S':
				{
					m_backMove = FALSE;
				}
				break;
			case 'D':
				{
					m_rightMove = FALSE;
				}
				break;
			}
		}
		break;

	case WM_LBUTTONDOWN:
		{
			m_yawPitchRotation = TRUE;
		}
		break;
	case WM_LBUTTONUP:
		{
			m_yawPitchRotation = FALSE;
		}
		break;

	case WM_RBUTTONDOWN:
		{
			m_rollRotation = TRUE;
		}
		break;
	case WM_RBUTTONUP:
		{
			m_rollRotation = FALSE;
		}
		break;

	case WM_MOUSEMOVE:
		{
			int curPosX = (int)(LOWORD(lParam));
			int curPosY = (int)(HIWORD(lParam));

			float dx = static_cast<float>(curPosX - m_mousePosX);
			float dy = static_cast<float>(curPosY - m_mousePosY);

			m_mousePosX = curPosX;
			m_mousePosY = curPosY;

			float rate = 0.01f;
			if( m_yawPitchRotation )
			{
				float yaw = dx * rate;
				float pitch = dy * rate;

				Matrix rotation;
				rotation.MakeRotation( yaw, pitch, 0.f );

				m_cameraTransform.PreMultiply( rotation );
			}
			else if( m_rollRotation )
			{
				float roll = dx * rate + dy * rate;

				Matrix rotation;
				rotation.MakeRotation( 0.f, 0.f, roll );

				m_cameraTransform.PreMultiply( rotation );
			}
		}
		break;
	}
}

